//package org.jwd.storage.aop;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import org.aopalliance.intercept.MethodInvocation;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.jwd.core.anno.AuditRecord;
//import org.jwd.core.consts.DictCategory;
//import org.jwd.core.consts.OptType;
//import org.jwd.core.entity.AuditEntity;
//import org.jwd.core.entity.AuthEntity;
//import org.jwd.storage.service.AuditService;
//import org.jwd.storage.service.AuthService;
//import org.jwd.storage.service.DataDictService;
//import org.springframework.aop.support.AopUtils;
//import org.springframework.beans.BeansException;
//import org.springframework.beans.factory.BeanFactory;
//import org.springframework.beans.factory.BeanFactoryAware;
//import org.springframework.core.BridgeMethodResolver;
//import org.springframework.stereotype.Component;
//import org.springframework.util.ClassUtils;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Method;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * @author vizz
// * @since 2022/5/20 16:24
// * 模板方法，定义了一个审计切面的步骤
// */
//@Component
//public class AuditTemplate{
//
//    private OptType optType = null;
//    private String EntityClassSimpleName = null;
//    private boolean paramIsId = false;
//    private static BeanFactory beanFactory;
//
//    public AuditRecord getAnnoInfo(MethodInvocation methodInvocation) {
//        return null;
//    }
//
//    public AuditRecord getAnnoInfo(ProceedingJoinPoint joinPoint) {
//        return null;
//    }
//
//    public void initFromAuditRecord(AuditRecord auditRecord) {
//        if (auditRecord != null) {
//            this.optType = auditRecord.optType();
//            this.paramIsId = auditRecord.paramIsId();
//        }
//    }
//
//    //调用proceed后
//
//    public static String getAuthorization() {
//        // 这里获取请求头的信息。不出意外的话这段代码肯定能在shiro和spring security中看到，我先立个flag。
//        // TODO：shiro和spring security有无类似代码？
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        String authorization = request.getHeader("Authorization");//TODO：取session，前端注意完善一下
//        return authorization;
//    }
//
//
//   public Object excute(){
//       Class<?> targetClass = methodInvocation.getThis() != null ? AopUtils.getTargetClass(methodInvocation.getThis()) : null;
//       Method specificMethod = ClassUtils.getMostSpecificMethod(methodInvocation.getMethod(), targetClass);
//       if (!specificMethod.getDeclaringClass().equals(Object.class)) {
//           final Method method = BridgeMethodResolver.findBridgedMethod(specificMethod);
//           final AuditRecord auditRecord = getAnnotation(method, targetClass, AuditRecord.class);
//           if (auditRecord != null) {
//               optType = auditRecord.optType();
//               entityClassSimpleName = method.getParameterTypes()[0].getSimpleName();
//               paramIsId = auditRecord.paramIsId();
//           }
//       }
//
//       //2.继续回到之前的方法调用（因为可能要用到id，而id在insert执行后才能有）
//       Object result = methodInvocation.proceed();
//
//       //3.获取调用的参数
//       Object[] args = methodInvocation.getArguments();
//       Map<String, Object> map = new HashMap<>();
//       if (paramIsId) {
//           map.put("id", args[0]);
//       } else {
//           try {
//               map = JSONObject.parseObject(JSON.toJSONString(args[0]));
//           } catch (Exception e) {
//               log.warn("对象转换失败，请检查方法入参是否为键值对象");
//           }
//
//       }
//
//       // 这里获取请求头的信息。不出意外的话这段代码肯定能在shiro和spring security中看到，我先立个flag。
//       // TODO：shiro和spring security有无类似代码？
//       ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//       HttpServletRequest request = attributes.getRequest();
//       String authorization = request.getHeader("Authorization");//TODO：取session，前端注意完善一下
//
//       //4.记录到审计表
//       AuditService auditService = SpringContextUtils.getBean(AuditService.class);
//       DataDictService dataDictService = SpringContextUtils.getBean(DataDictService.class);
//       AuthService authService = SpringContextUtils.getBean(AuthService.class);
//
//       AuthEntity authEntity = authService.findByValidation(authorization);
//       Long optUserId = 0L;
//       if (authEntity != null) {
//           optUserId = authEntity.getUserId();
//       }
//       /**
//        * private Long userId;
//        * private String operate;//权限:级别
//        * private String paramJson;//json格式的param对象
//        * private String tableName;//影响了哪张表
//        * private Long rowId;//影响了哪一列
//        * private LocalDateTime operateTime;
//        * private String ip;
//        */
//       Integer id = (Integer) map.get("id");
//       AuditEntity auditEntity = new AuditEntity()
//               .setUserId(optUserId)
//               .setOperate(optType.name())
//               .setParamJson(JSON.toJSONString(args))
//               .setTableName(dataDictService.getByKeyAndCtg(entityClassSimpleName, DictCategory.ENTITY2TABLE))
//               .setRowId(id.longValue())
//               .setIp(request.getRemoteAddr());
//
//       auditService.save(auditEntity);
//
//       //5.原方法继续执行
//       return result;
//   }
//}
